home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / programming / other / mesa / mesa-glut / src-glut.aos / glutattachdetachmenu.c < prev    next >
C/C++ Source or Header  |  2000-02-23  |  6KB  |  220 lines

  1. /*
  2.  * Amiga GLUT graphics library toolkit
  3.  * Version:  1.1
  4.  * Copyright (C) 1998 Jarno van der Linden
  5.  *
  6.  * This library is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Library General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * This library is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Library General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Library General Public
  17.  * License along with this library; if not, write to the Free
  18.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. /*
  22.  * glutAttachDetachMenu.c
  23.  *
  24.  * Version 1.0  27 Jun 1998
  25.  * by Jarno van der Linden
  26.  * jarno@kcbbs.gen.nz
  27.  *
  28.  */
  29.  
  30. #include <stdlib.h>
  31. #include <inline/gadtools.h>
  32. #include <inline/intuition.h>
  33. #include <libraries/gadtools.h>
  34. #include "glutstuff.h"
  35.  
  36. static struct Menu *GetMenuPointer(int button)
  37. {
  38.   struct GlutWindow *actWindow;
  39.   struct Menu *actMenu = NULL;
  40.  
  41.   if ((actWindow = glutstuff.curwin)) {
  42.     if ((actMenu = actWindow->menu)) {
  43.       switch (button) {
  44.     case GLUT_RIGHT_BUTTON:
  45.       actMenu = actMenu->NextMenu;
  46.     case GLUT_MIDDLE_BUTTON:
  47.       actMenu = actMenu->NextMenu;
  48.     case GLUT_LEFT_BUTTON:
  49.       break;
  50.       }
  51.     }
  52.   }
  53.  
  54.   return actMenu;
  55. }
  56.  
  57. /* TODO: use dList->nodes instead */
  58. static int CountMenuEntries(struct GlutMenu *gm)
  59. {
  60.   int n = 1;                                    /* This menu item */
  61.  
  62.   if (gm) {
  63.     struct GlutMenuEntry *actEntry = (struct GlutMenuEntry *)&gm->MenuEntries;
  64.  
  65.     while ((actEntry = (struct GlutMenuEntry *)nGetNext(&actEntry->EntryNode))) {
  66.       DEBUGOUT(5, "\tcount 0x%08x (`%s')\n", actEntry, actEntry->name);
  67.  
  68.       if (actEntry->issubmenu) {
  69.     if (actEntry->EntryMenu)
  70.       n += CountMenuEntries(actEntry->EntryMenu) + 2;            /* Will include (sub)menu item */
  71.     else
  72.       DEBUGOUT(1, "missing submenue for `%s'\n", actEntry->name);
  73.       }
  74.       else
  75.     n++;                                    /* Just this menu entry */
  76.     }
  77.   }
  78.  
  79.   return n;
  80. }
  81.  
  82. static void FillEntry(struct NewMenu **nm, UBYTE nm_type, const STRPTR nm_Label, APTR nm_UserData)
  83. {
  84.   (*nm)->nm_Type = nm_type;
  85.   (*nm)->nm_Label = (char *)nm_Label;
  86.   (*nm)->nm_CommKey = 0;
  87.   (*nm)->nm_Flags = 0;
  88.   (*nm)->nm_MutualExclude = 0;
  89.   (*nm)->nm_UserData = nm_UserData;
  90.   (*nm)++;
  91. }
  92.  
  93. static void FillMenu(struct GlutMenu *gm, struct NewMenu **nm, UBYTE type)
  94. {
  95.   if (gm) {
  96.     struct GlutMenuEntry *actEntry = (struct GlutMenuEntry *)&gm->MenuEntries;
  97.  
  98.     while ((actEntry = (struct GlutMenuEntry *)nGetNext(&actEntry->EntryNode))) {
  99.       DEBUGOUT(5, "\t  FillEntry(0x%08x, 0x%02x, `%s', 0x%08x);\n", *nm, type, actEntry->name, actEntry);
  100.       FillEntry(nm, type, actEntry->name, actEntry);
  101.  
  102.       if (actEntry->issubmenu) {
  103.     if (actEntry->EntryMenu) {
  104.       if (type == NM_SUB) {
  105.         ((*nm) - 1)->nm_Flags = NM_ITEMDISABLED;
  106.         DEBUGOUT(5, "\t  FillEntry(0x%08x, 0x%02x, \"--\");\n", *nm, type);
  107.         FillEntry(nm, type, NM_BARLABEL, 0);
  108.       }
  109.       DEBUGOUT(5, "\t  FillMenu(0x%08x, 0x%02x);\n", actEntry->EntryMenu, *nm);
  110.       FillMenu(actEntry->EntryMenu, nm, NM_SUB);
  111.       if (type == NM_SUB) {
  112.         DEBUGOUT(5, "\t  FillEntry(0x%08x, 0x%02x, \"--\");\n", *nm, type);
  113.         FillEntry(nm, type, NM_BARLABEL, 0);
  114.       }
  115.     }
  116.     else
  117.       DEBUGOUT(1, "missing submenue for `%s'\n", actEntry->name);
  118.       }
  119.     }
  120.   }
  121. }
  122.  
  123. static struct MenuItem *MakeMenu(struct GlutMenu *gm)
  124. {
  125.   struct NewMenu *nm, *nmp;
  126.   struct MenuItem *menu = NULL;
  127.  
  128.   if (gm) {
  129.     if ((nm = AllocVecPooled(glutPool, (CountMenuEntries(gm) + 1) * sizeof(struct NewMenu)))) {
  130.       nmp = nm;
  131.  
  132.       DEBUGOUT(5, "\t FillMenu(0x%08x, 0x%08x);\n", gm, nmp);
  133.       FillMenu(gm, &nmp, NM_ITEM);
  134.       DEBUGOUT(5, "\t FillEntry(0x%08x);\n", nmp);
  135.       FillEntry(&nmp, NM_END, NULL, 0);
  136.  
  137.       DEBUGOUT(5, "\t CreateMenus(0x%08x);\n", nm);
  138.       menu = (struct MenuItem *)CreateMenus(nm, TAG_END);
  139.       FreeVecPooled(glutPool, (ULONG *)nm);
  140.     }
  141.     else
  142.       DEBUGOUT(1, "failed to allocate new menu\n");
  143.   }
  144.  
  145.   return menu;
  146. }
  147.  
  148. void RedoMenu(int button, struct GlutMenu *glutmenu)
  149. {
  150.   struct GlutWindow *actWindow;
  151.   struct Menu *menu;
  152.   struct MenuItem *menuitems;
  153.  
  154.   if ((actWindow = glutstuff.curwin) && (actWindow->window) && (actWindow->menu)) {
  155.     if ((menu = GetMenuPointer(button))) {
  156.       DEBUGOUT(5, "\tClearMenuStrip(0x%08x);\n", actWindow->window);
  157.       ClearMenuStrip(actWindow->window);
  158.       DEBUGOUT(5, "\tFreeMenus(0x%08x);\n", menu->FirstItem);
  159.       FreeMenus(menu->FirstItem);                        /* TODO: cast */
  160.  
  161.       if (glutmenu && (menuitems = MakeMenu(glutmenu))) {
  162.     menu->FirstItem = menuitems;
  163.     DEBUGOUT(5, "\tLayoutMenuItems(0x%08x, 0x%08x, 0x%08x, 0x%08x);\n", menuitems, actWindow->vi, GTMN_Menu, (ULONG) menu);
  164.     LayoutMenuItems(menuitems, actWindow->vi,
  165.             GTMN_Menu, (ULONG) menu,
  166.             TAG_END);
  167.       }
  168.       else
  169.     menu->FirstItem = NULL;
  170.  
  171.       DEBUGOUT(5, "\tSetMenuStrip(0x%08x, 0x%08x);\n", actWindow->window, actWindow->menu);
  172.       SetMenuStrip(actWindow->window, actWindow->menu);
  173.     }
  174.   }
  175. }
  176.  
  177. void glutAttachMenu(int button)
  178. {
  179.   struct GlutWindow *actWindow;
  180.  
  181.   if ((actWindow = glutstuff.curwin)) {
  182.     switch (button) {
  183.       case GLUT_LEFT_BUTTON:
  184.     actWindow->leftmenu = glutstuff.curmenu;
  185.     actWindow->needleftmenu = TRUE;
  186.     break;
  187.       case GLUT_MIDDLE_BUTTON:
  188.     actWindow->middlemenu = glutstuff.curmenu;
  189.     actWindow->needmiddlemenu = TRUE;
  190.     break;
  191.       case GLUT_RIGHT_BUTTON:
  192.     actWindow->rightmenu = glutstuff.curmenu;
  193.     actWindow->needrightmenu = TRUE;
  194.     break;
  195.     }
  196.   }
  197. }
  198.  
  199. void glutDetachMenu(int button)
  200. {
  201.   struct GlutWindow *actWindow;
  202.  
  203.   if ((actWindow = glutstuff.curwin)) {
  204.     switch (button) {
  205.       case GLUT_LEFT_BUTTON:
  206.     actWindow->leftmenu = NULL;
  207.     actWindow->needleftmenu = TRUE;
  208.     break;
  209.       case GLUT_MIDDLE_BUTTON:
  210.     actWindow->middlemenu = NULL;
  211.     actWindow->needmiddlemenu = TRUE;
  212.     break;
  213.       case GLUT_RIGHT_BUTTON:
  214.     actWindow->rightmenu = NULL;
  215.     actWindow->needrightmenu = TRUE;
  216.     break;
  217.     }
  218.   }
  219. }
  220.